﻿using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
//using Unity.Mathematics;
using UnityEngine;
using UnityEngine.SceneManagement;

//游戏主要状态
public enum GameState
{
    Free = 1, //空闲状态
    Fall = 2, //第一次下落状态
    Match = 3, //三消状态
    Result = 4, //结果状态
    Battle = 5, //使用物品状态 攻防血等
    EnemyDead = 6, //敌人死亡状态
    WinLose = 7, //胜利失败状态
}

public struct Element_struct
{
    public Vector2 v2;
    public int id;

    public Element_struct(Vector2 v2, int id)
    {
        this.v2 = v2;
        this.id = id;
    }
}


public class CellFunctions
{
    public static List<List<List<int>>> lists = new List<List<List<int>>>
    {
        new List<List<int>>
        {
            new List<int> {0,1,0},
            new List<int> {1,1,1},
            new List<int> {0,0,0},
        },
        new List<List<int>>
        {
            new List<int> {0,1,0},
            new List<int> {0,1,1},
            new List<int> {0,0,1},
        },
        //new List<List<int>>
        //{
        //    new List<int> {0,0,1},
        //    new List<int> {0,1,1},
        //    new List<int> {0,1,0},
        //},
        //new List<List<int>>
        //{
        //    new List<int> {0,1,0},
        //    new List<int> {0,1,0},
        //    new List<int> {0,1,0},
        //},
        //new List<List<int>>
        //{
        //    new List<int> {0,1,0},
        //    new List<int> {1,1,1},
        //    new List<int> {0,1,0},
        //},
    };



    public static int safeCount = 0; //递归防止卡死参数，没什么别的用
    
    //生成元素
    public static Element CreateElement(int _x, int _y, int _type = 1)
    {
        GameObject go = GameObject.Instantiate(ShuaiManager.Instance.prefab_Element, Vector3.zero, Quaternion.identity, ShuaiManager.Instance.ParentElement.transform);
        Element element = go.GetComponent<Element>();
        element.Init();


        
        //int x1 = Mathf.FloorToInt(ShuaiManager.Instance.col / 2) - 1; //Random.Range(0, ShuaiManager.Instance.col);
        //int y1 = ShuaiManager.Instance.row - 1 - 1;
        //Cell cell1 = CellFunctions.CreateCell(UnityEngine.Random.Range(1, ShuaiManager.Instance.type_count + 1), x1, y1, ShuaiManager.Instance.cellList);

        //element.cellList2[1][1] = cell1;

        //Vector2 dir = Vector2.right;
        //element.dir = dir;

        //Cell cell2 = CellFunctions.CreateCell(UnityEngine.Random.Range(1, ShuaiManager.Instance.type_count + 1), x1 + (int)dir.x, y1 + (int)dir.y, ShuaiManager.Instance.cellList);
        //element.cellList2[1 + (int)dir.x][1 + (int)dir.y] = cell2;




        return element;
    }

    //生成格子
    public static Grid CreateGrid(int _x, int _y)
    {
        GameObject go = GameObject.Instantiate(ShuaiManager.Instance.prefab_Grid, Vector3.zero, Quaternion.identity, ShuaiManager.Instance.ParentGrid.transform); 
        Grid grid = go.GetComponent<Grid>();
        grid.Init(_x, _y);

        return grid;
    }

    //生成元素
    public static Cell CreateCell(int _id, int _x, int _y, List<List<Cell>> cellList)
    {
        if (_id <= 0)
        {
            return null;
        }

        GameObject go = GameObject.Instantiate(ShuaiManager.Instance.prefab_Cell, Vector3.zero, Quaternion.identity, ShuaiManager.Instance.ParentCell.transform);
        Cell cell = go.GetComponent<Cell>();
        cell.Init(_id, _x, _y);
        if (cellList != null)
        {
            cellList[_x][_y] = cell;
        }
        
        cell.Refresh();

        return cell;
    }

    //生成最上面一行元素
    //目前采用一种保底机制，保证每种元素至少随机出一个
    public static void CreateTopLine(int _row = 0)
    {
        int y = _row - 1;
        for (int x = 0; x <= ShuaiManager.Instance.col - 1; x++)
        {
            int id = UnityEngine.Random.Range(1, ShuaiManager.Instance.type_count + 1);
            Cell cell = CellFunctions.CreateCell(id, x, y, ShuaiManager.Instance.cellList);
            //cell.isMove = true;
            cell.Refresh();
        }

        ////目前采用一种保底机制，保证每种元素至少随机出一个
        int[] items = ShuaiFunctions.GetRandomArray(ShuaiManager.Instance.type_count, 0, ShuaiManager.Instance.col - 1);
        for (int i = 0; i < items.Length; i++)
        {
            int x = items[i];
            Cell cell = ShuaiManager.Instance.cellList[x][y];
            cell.id = i + 1;
            cell.Refresh();
        }
    }

    public static List<Cell> Check(Cell cell, List<Cell> list)
    {
        if (list == null)
        {
            list = new List<Cell>();
        }

        if (cell == null)
        {
            return null;
        }

        if (list.Contains(cell))
        {
            return list;
        }
        else
        {
            list.Add(cell);
        }

        int x = cell.x;
        int y = cell.y;
        Cell cell_up = GetCell(x, y + 1);
        Cell cell_down = GetCell(x, y - 1);
        Cell cell_left = GetCell(x - 1, y);
        Cell cell_right = GetCell(x + 1, y);

        if (cell_up != null && cell.id == cell_up.id)
        {
            Check(cell_up, list);
        }
        if (cell_down != null && cell.id == cell_down.id)
        {
            Check(cell_down, list);
        }
        if (cell_left != null && cell.id == cell_left.id)
        {
            Check(cell_left, list);
        }
        if (cell_right != null && cell.id == cell_right.id)
        {
            Check(cell_right, list);
        }
        
        return list;
    }

    //检测所有相邻并有相同id元素的Cell，组成列表
    public static List<List<Cell>> GetAllSameList()
    {
        List<List<Cell>> lists = new List<List<Cell>>();

        for (int x = 0; x < ShuaiManager.Instance.col; x++)
        {
            for (int y = 0; y < ShuaiManager.Instance.row; y++)
            {
                Cell cell = ShuaiManager.Instance.cellList[x][y];
                bool isContains = false;
                foreach (var list in lists)
                {
                    if (list != null && list.Contains(cell))
                    {
                        isContains = true;
                    }
                }
                if (isContains == false)
                {
                    List<Cell> sameList = CellFunctions.Check(cell, null);
                    lists.Add(sameList);
                }
            }
        }

        return lists;
    }

    //通过x和y获得一个指定Cell
    public static Cell GetCell(int x, int y)
    {
        Cell cell = null;

        if (x >= 0 && x <= ShuaiManager.Instance.col - 1 &&
            y >= 0 && y <= ShuaiManager.Instance.row - 1)
        {
            cell = ShuaiManager.Instance.cellList[x][y];
        }

        return cell;
    }

    public static Cell RandomEmptyCell()
    {
        List<Cell> list1 = new List<Cell>();

        for (int x = 0; x < ShuaiManager.Instance.col; x++)
        {
            for (int y = 0; y < ShuaiManager.Instance.row; y++)
            {
                Cell targetCell = ShuaiManager.Instance.cellList[x][y];
                if (targetCell.id == 0)
                {
                    list1.Add(targetCell);
                }
            }
        }

        int index = UnityEngine.Random.Range(0, list1.Count);
        Cell cell = list1[index];

        return cell;
    }

    //获取从下到上一列中第一个为空的Cell
    public static int GetFirstEmptyCellY(int x)
    {
        int firstEmptyCell_Y = 0;

        for (int y = 0; y <= ShuaiManager.Instance.row - 1; y++)
        {
            Cell item_cell = ShuaiManager.Instance.cellList[x][y];
            if (item_cell == null)
            {
                firstEmptyCell_Y = y;
                break;
            }
        }

        return firstEmptyCell_Y;
    }

    public static void MoveAll(Vector2 _direction)
    {
        int startIndex_x = 0;
        int endIndex_x = ShuaiManager.Instance.col - 1;
        int startIndex_y = 0;
        int endIndex_y = ShuaiManager.Instance.row - 1;
        int add_x = 1;
        int add_y = 1;

        if (_direction == Vector2.up)
        {
            startIndex_y = ShuaiManager.Instance.row - 1;
            endIndex_y = 0;
            add_y = -1;
        }
        else if (_direction == Vector2.down)
        {
            startIndex_y = 0;
            endIndex_y = ShuaiManager.Instance.row - 1;
            add_y = +1;
        }
        else if (_direction == Vector2.left)
        {
            startIndex_x = 0;
            endIndex_x = ShuaiManager.Instance.col - 1;
            add_x = +1;
        }
        else if (_direction == Vector2.right)
        {
            startIndex_x = ShuaiManager.Instance.col - 1;
            endIndex_x = 0;
            add_x = -1;
        }

        for (int x = startIndex_x; _direction == Vector2.right ? x >= endIndex_x : x <= endIndex_x; x = x + add_x)
        {
            //Debug.Log(x);
            for (int y = startIndex_y; _direction == Vector2.up ? y >= endIndex_y : y <= endIndex_y; y = y + add_y)
            {
                //Debug.Log(y);
                Cell cell = ShuaiManager.Instance.cellList[x][y];
                if (cell != null)
                {
                    ShuaiManager.Instance.cellList[cell.x][cell.y] = null;

                    cell.x += (int)_direction.x;
                    cell.y += (int)_direction.y;
                    
                    cell.Refresh();
                    cell.RefreshPos();

                    ShuaiManager.Instance.cellList[cell.x][cell.y] = cell;
                }
            }
        }
    }

    //下移到不能下移的位置
    public static bool MoveDownCell(int _x, int _y)
    {
        bool isMove = false;

        Cell cell = ShuaiManager.Instance.cellList[_x][_y];
        if (cell != null)
        {
            int firstEmptyCell_Y = CellFunctions.GetFirstEmptyCellY(_x);
            if (firstEmptyCell_Y != -1 && cell.y > firstEmptyCell_Y)
            {
                isMove = true;
                ShuaiManager.Instance.movingCellList.Add(cell);
                int y = cell.y;
                cell.Set(_x, firstEmptyCell_Y);
                Vector3 pos = CellFunctions.GetPos(cell.x, firstEmptyCell_Y);
;
                Tweener tweener = cell.transform.DOMoveY(pos.y, 0.05f * (y - firstEmptyCell_Y));
                tweener.SetEase(Ease.Flash);
                tweener.onComplete = () =>
                {
                    if (ShuaiManager.Instance.movingCellList.Contains(cell))
                    {
                        ShuaiManager.Instance.movingCellList.Remove(cell);
                    }

                    if (ShuaiManager.Instance.movingCellList.Count <= 0)
                    {
                        ShuaiFunctions.DelayFunction(() =>
                        {
                            CellFunctions.KillAllSameList();
                        }, 0.2f);
                    }
                };
            }
        }

        return isMove;
    }

    //所有下移
    public static bool MoveDownAllCell()
    {
        ShuaiManager.Instance.gameState = GameState.Fall;

        bool isMove = false;

        for (int x = 0; x <= ShuaiManager.Instance.col - 1; x++)
        {
            for (int y = 0; y <= ShuaiManager.Instance.row - 1; y++)
            {
                bool oneMove = CellFunctions.MoveDownCell(x, y);
                if (oneMove == true)
                {
                    isMove = true;
                }
            }
        }

        if (isMove == true)
        {
            //ShuaiFunctions.DelayFunction(() =>
            //{
            //    Debug.Log("KillAllSameList");
            //    KillAllSameList();
            //}, 0.4f);
        }
        else
        {
            //TipPanel.Instance.Open("结束下移");
            ShuaiManager.Instance.RoundEnd();
        }

        return isMove;
    }

    //三消
    public static bool KillAllSameList()
    {
        ShuaiManager.Instance.gameState = GameState.Match;

        bool isKill = false;

        List<List<Cell>> lists = GetAllSameList();
        if (lists != null)
        {
            foreach (var list in lists)
            {
                if (list != null)
                {
                    if (list.Count >= ShuaiManager.Instance.killNumber)
                    {
                        Cell cell = list[0];
                        
                        isKill = true;
                        Color color = new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), 1);
                        foreach (var item_cell in list)
                        {
                            item_cell.Dead();
                        }
                    }
                }
            }
        }

        if (isKill == true)
        {
            ShuaiFunctions.DelayFunction(() =>
            {
                MoveDownAllCell();
            }, 0.4f);
        }
        else
        {
            //TipPanel.Instance.Open("结束三消");
            ShuaiManager.Instance.RoundEnd();
        }

        return isKill;
    }

    //最上面的一行左移或右移动一格
    public static void MoveLefOrRight(Vector2 _dir, int _row)
    {
        if (ShuaiManager.Instance.gameState != GameState.Free)
        {
            return;
        }

        List<Cell> topIdList = new List<Cell>();
        List<int> copyIdList = new List<int>();

        int y = _row - 1;
        for (int x = 0; x <= ShuaiManager.Instance.col - 1; x++)
        {
            //int y = ShuaiManager.Instance.row - 1;
            Cell cell = ShuaiManager.Instance.cellList[x][y];
            topIdList.Add(cell);
        }
        topIdList.ForEach(item => copyIdList.Add(item.id));


        for (int x = 0; x <= topIdList.Count - 1; x++)
        {
            Cell cell = topIdList[x];
            int nextIndex = x;
            if (_dir == Vector2.left)
            {
                nextIndex = x + 1;
                if (nextIndex > topIdList.Count - 1)
                {
                    nextIndex = 0;
                }
            }
            else if (_dir == Vector2.right)
            {
                nextIndex = x - 1;
                if (nextIndex < 0)
                {
                    nextIndex = topIdList.Count - 1;
                }
            }
            
            cell.id = copyIdList[nextIndex];
            cell.Refresh();
        }
    }

    //清除所有
    public static void ClearAll()
    {
        if (ShuaiManager.Instance.cellList == null)
        {
            return;
        }

        for (int x = 0; x <= ShuaiManager.Instance.col - 1; x++)
        {
            for (int y = 0; y <= ShuaiManager.Instance.row - 1 + ShuaiManager.Instance.add_row; y++)
            {
                Cell cell = ShuaiManager.Instance.cellList[x][y];
                if (cell != null)
                {
                    cell.Dead();
                }
            }
        }
    }

    public static void RefreshAll()
    {
        for (int x = 0; x < ShuaiManager.Instance.col; x++)
        {
            for (int y = 0; y < ShuaiManager.Instance.row; y++)
            {
                Cell cell = ShuaiManager.Instance.cellList[x][y];
                cell.Refresh();
            }
        }
    }

    //攻击线
    public static void Shoot(Vector3 _pos1, Vector3 _pos2, VoidDelegate _callback = null)
    {
        //GameObject go = GameObject.Instantiate(ShuaiManager.Instance.prefab_Line, Vector3.zero, Quaternion.identity, ShuaiManager.Instance.ParentEffect.transform);
        //go.name = "攻击线";
        //Line line = go.GetComponent<Line>();
        //line.Shoot(_pos1, _pos2, _callback);


        GameObject go = GameObject.Instantiate(ShuaiManager.Instance.prefab_Cell, Vector3.zero, Quaternion.identity, ShuaiManager.Instance.ParentEffect.transform);
        go.transform.position = _pos1;

        float angle = _pos1.x < _pos2.x ? 220f : 220f + 180f;
        Tweener tweener1 = go.transform.DOLocalRotate(new Vector3(0, 0, angle + UnityEngine.Random.Range(-30f, +30f)), 0.4f, RotateMode.WorldAxisAdd);
        //tweener1.SetEase(Ease.Flash);
        tweener1.onComplete = () =>
        {
            Tweener tweener = go.transform.DOMove(_pos2, 0.4f);
            tweener.SetEase(Ease.InBack);
            tweener.onComplete = () =>
            {
                GameObject.Destroy(go.gameObject);
                _callback();
            };
        };
    }

    //获取team方角色
    //public static Character GetMyCharacter(Team team)
    //{
    //    foreach (var item in ShuaiManager.Instance.characterList)
    //    {
    //        if (item.team == team)
    //        {
    //            return item;
    //        }
    //    }

    //    return null;
    //}

    

    public static float GetPosX(int _x)
    {
        float cellSize = ShuaiManager.Instance.cellSize;
        float x = cellSize * _x - ShuaiManager.Instance.width / 2 + cellSize / 2;
        return x;
    }

    public static float GetPosY(int _y)
    {
        float cellSize = ShuaiManager.Instance.cellSize;
        float y = cellSize * _y - ShuaiManager.Instance.height_screen / 2 + cellSize / 2 + ShuaiManager.Instance.paddingBottom;
        return y;
    }

    public static Vector3 GetPos(int _x, int _y)
    {
        float x = GetPosX(_x);
        float y = GetPosY(_y);
        Vector3 pos = new Vector3(x, y, 0);
        return pos;
    }

    //废弃的
    //废弃的
    //废弃的
    //public static void Select(Cell cell, bool active)
    //{
    //    for (int x = 0; x < ShuaiManager.Instance.col; x++)
    //    {
    //        for (int y = 0; y < ShuaiManager.Instance.row; y++)
    //        {
    //            Cell item_cell = ShuaiManager.Instance.cellList[x][y];
    //            item_cell.isSelect = false;
    //            item_cell.Refresh();
    //        }
    //    }

    //    cell.isSelect = active;
    //    cell.Refresh();
    //}

    //public static Cell GetSelectCell()
    //{
    //    Cell cell = null;

    //    for (int x = 0; x < ShuaiManager.Instance.col; x++)
    //    {
    //        for (int y = 0; y < ShuaiManager.Instance.row; y++)
    //        {
    //            Cell item_cell = ShuaiManager.Instance.cellList[x][y];
    //            if (item_cell.isSelect == true)
    //            {
    //                cell = item_cell;
    //            }
    //        }
    //    }

    //    return cell;
    //}
}
